package service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import constants.ConfigConstant;
import dao.ListeningInfoMapper;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import orm.dto.ServiceBusDetailDTO;
import orm.dto.ServiceTrainDTO;
import orm.po.ListeningInfo;
import utils.HttpUtils;
import utils.MyDateUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author yuyufeng
 * @date 2018/2/7
 */
@Service
public class ListeningService {
    @Autowired
    private ListeningInfoMapper listeningInfoMapper;
    @Autowired
    private BusService busService;
    @Autowired
    private TrainService trainService;
    @Resource(name = "redisTemplate")
    private ValueOperations<String, String> valueOs;

    private final Logger LOG = LoggerFactory.getLogger(this.getClass());

    public List<ListeningInfo> listByUserId(int page, int rows, Long userId) {
        PageHelper.startPage(page, rows, "create_time desc");
        return listeningInfoMapper.listByUserId(userId);
    }

    public List<ListeningInfo> listListeningList(int page, int rows) {
        PageHelper.startPage(page, rows, "create_time asc");
        return listeningInfoMapper.listListeningList();
    }


    /**
     * @param listeningInfoPO
     */
    public void listeningTrainItem(ListeningInfo listeningInfoPO) {
        String listeningObject = listeningInfoPO.getListeningObject();
        Integer listeningType = listeningInfoPO.getListeningType();
        String[] listenItems = listeningObject.split("\\|");
        String begin = listenItems[0];
        String end = listenItems[1];
        String date = listenItems[2];
        String time = listenItems[3];
        String no = listenItems[4];
        String keywordsStr1;
        String keywordsStr2;

        overdue(listeningInfoPO, date, time);


        try {
            ListeningInfo record = new ListeningInfo();
            record.setListeningId(listeningInfoPO.getListeningId());
            record.setListeningTimes(listeningInfoPO.getListeningTimes() + 1);

            List<ServiceTrainDTO> list = trainService.searchTrainList(begin, end, date);


            //监听成功次数
            if (list != null && list.size() > 0) {
                record.setListeningSuccess(listeningInfoPO.getListeningSuccess() + 1);
            }

            for (ServiceTrainDTO serviceTrainDTO : list) {
                if (time.equals(serviceTrainDTO.getBeginTime()) && no.equals(serviceTrainDTO.getTrainNo())) {
                    LOG.info("监听到车次" + JSONObject.toJSON(serviceTrainDTO));
                    int seat2 = 0;
                    int hardBed = 0;
                    int hardSeat = 0;

                    try {
                        seat2 = Integer.valueOf(serviceTrainDTO.getSeat2());
                    } catch (Exception e) {
                    }

                    try {
                        hardBed = Integer.valueOf(serviceTrainDTO.getBedHard());
                    } catch (Exception e) {
                    }

                    try {
                        hardSeat = Integer.valueOf(serviceTrainDTO.getSeatHard());
                    } catch (Exception e) {
                    }

                    if(seat2 > 0){
                        record.setListeningSeatLeft(seat2);
                        record.setListeningSeat("二等座");
                    }else if(hardBed >0){
                        record.setListeningSeatLeft(hardBed);
                        record.setListeningSeat("硬卧");
                    }else if(hardSeat >0){
                        record.setListeningSeatLeft(hardSeat);
                        record.setListeningSeat("硬座");
                    }



                    if (0 == listeningType) {

                        if ("有".equals(serviceTrainDTO.getSeat2()) || seat2 > 0) {
                            record.setListeningSeat(serviceTrainDTO.getSeat2());
                            LOG.info("通知用户有票了");
                            keywordsStr1 = "车次[" + listeningInfoPO.getListeningObject() + "]有余票了";
                            keywordsStr2 = "如有需要，请尽快通过官方渠道（12306.cn）购买";
                            //推送通知客户
                            pushMP(keywordsStr1, keywordsStr2, listeningInfoPO.getMpOpenId(), listeningInfoPO.getFormId());
                            record.setListeningSeat("二等座");
                            record.setNotified(1);
                        } else if ("有".equals(serviceTrainDTO.getBedHard()) || hardBed > 0) {
                            record.setListeningSeat(serviceTrainDTO.getBedHard());
                            LOG.info("通知用户有票了");
                            keywordsStr1 = "车次[" + listeningInfoPO.getListeningObject() + "]有余票了";
                            keywordsStr2 = "如有需要，请尽快通过官方渠道（12306.cn）购买";
                            //推送通知客户
                            pushMP(keywordsStr1, keywordsStr2, listeningInfoPO.getMpOpenId(), listeningInfoPO.getFormId());
                            record.setListeningSeat("硬卧");
                            record.setNotified(1);
                        } else if ("有".equals(serviceTrainDTO.getSeatHard()) || hardSeat > 0) {
                            record.setListeningSeat(serviceTrainDTO.getSeatHard());
                            LOG.info("通知用户有票了");
                            keywordsStr1 = "车次[" + listeningInfoPO.getListeningObject() + "]有余票了";
                            keywordsStr2 = "如有需要，请尽快通过官方渠道（12306.cn）购买";
                            //推送通知客户
                            pushMP(keywordsStr1, keywordsStr2, listeningInfoPO.getMpOpenId(), listeningInfoPO.getFormId());
                            record.setListeningSeat("硬座");
                            record.setNotified(1);
                        }

                    } else if (1 == listeningType) {
                        //推送通知客户

                        if ("有".equals(serviceTrainDTO.getSeat2()) || seat2 > 4 || "有".equals(serviceTrainDTO.getBedHard()) || hardBed > 4 || "有".equals(serviceTrainDTO.getSeatHard()) || hardSeat > 4) {
                            break;
                        }

                        if ( seat2 < 5) {
                            record.setListeningSeatLeft(seat2);
                            LOG.info("通知用户余票过少");
                            keywordsStr1 = "车次[" + listeningInfoPO.getListeningObject() + "]余票只剩" + seat2 + "张了";
                            keywordsStr2 = "如有需要，请尽快通过官方渠道（12306.cn）购买";
                            //推送通知客户
                            pushMP(keywordsStr1, keywordsStr2, listeningInfoPO.getMpOpenId(), listeningInfoPO.getFormId());
                            record.setListeningSeat("二等座");
                            record.setNotified(1);
                        } else if (hardBed < 5) {
                            record.setListeningSeatLeft(seat2);
                            LOG.info("通知用户余票过少");
                            keywordsStr1 = "车次[" + listeningInfoPO.getListeningObject() + "]余票只剩" + hardBed + "张了";
                            keywordsStr2 = "如有需要，请尽快通过官方渠道（12306.cn）购买";
                            //推送通知客户
                            pushMP(keywordsStr1, keywordsStr2, listeningInfoPO.getMpOpenId(), listeningInfoPO.getFormId());
                            record.setListeningSeat("硬卧");
                            record.setNotified(1);
                        } else if ( hardSeat < 5) {
                            record.setListeningSeatLeft(hardSeat);
                            LOG.info("通知用户余票过少");
                            keywordsStr1 = "车次[" + listeningInfoPO.getListeningObject() + "]余票只剩" + hardSeat + "张了";
                            keywordsStr2 = "如有需要，请尽快通过官方渠道（12306.cn）购买";
                            //推送通知客户
                            pushMP(keywordsStr1, keywordsStr2, listeningInfoPO.getMpOpenId(), listeningInfoPO.getFormId());
                            record.setListeningSeat("硬座");
                            record.setNotified(1);
                        }
                    }
                    break;
                }
            }


            //更新数据库
            record.setUpdateTime(new Date());
            listeningInfoMapper.updateByPrimaryKeySelective(record);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    /**
     * @param listeningInfoPO
     */
    public void listeningBusItem(ListeningInfo listeningInfoPO) {
        String listeningObject = listeningInfoPO.getListeningObject();
        Integer listeningType = listeningInfoPO.getListeningType();
        String[] listenItems = listeningObject.split("\\|");
        String begin = listenItems[0];
        String end = listenItems[1];
        String date = listenItems[2];
        String time = listenItems[3];
        String no = listenItems[4];
        String keywordsStr1;
        String keywordsStr2;
        //过期车次
        overdue(listeningInfoPO, date, time);

        try {
            List<ServiceBusDetailDTO> list = busService.listBus(begin, end, date);
            ListeningInfo record = new ListeningInfo();
            record.setListeningId(listeningInfoPO.getListeningId());
            record.setListeningTimes(listeningInfoPO.getListeningTimes() + 1);

            //监听成功次数
            if (list != null && list.size() > 0) {
                record.setListeningSuccess(listeningInfoPO.getListeningSuccess() + 1);
            }

            for (ServiceBusDetailDTO serviceBusDetailDTO : list) {
                if (time.equals(serviceBusDetailDTO.getBusTime()) && no.equals(serviceBusDetailDTO.getBusNo())) {
                    LOG.info("监听到车次" + JSONObject.toJSON(serviceBusDetailDTO));
                    Integer left = Integer.valueOf(serviceBusDetailDTO.getTicketLeft());
                    record.setListeningSeatLeft(left);
                    if (2 == listeningType) {
                        // 2,汽车票有票提醒
                        if (left > 0) {
                            //推送通知客户
                            LOG.info("通知用户有票了");
                            keywordsStr1 = "车次[" + listeningInfoPO.getListeningObject() + "]有余票" + left + "张了";
                            keywordsStr2 = "如有需要，请尽快通过官方渠道（" + serviceBusDetailDTO.getDataFrom() + "）购买";
                            //推送通知客户
                            pushMP(keywordsStr1, keywordsStr2, listeningInfoPO.getMpOpenId(), listeningInfoPO.getFormId());
                            //更新数据库
                            record.setNotified(1);
                        }
                    } else if (3 == listeningType) {
                        // 3,汽车票过少提醒
                        if (left < 5) {
                            //推送通知客户
                            LOG.info("通知用户余票过少");
                            keywordsStr1 = "车次[" + listeningInfoPO.getListeningObject() + "]余票只剩" + left + "张了";
                            keywordsStr2 = "如有需要，请尽快通过官方渠道（" + serviceBusDetailDTO.getDataFrom() + "）购买";
                            //推送通知客户
                            pushMP(keywordsStr1, keywordsStr2, listeningInfoPO.getMpOpenId(), listeningInfoPO.getFormId());
                            //更新数据库
                            record.setNotified(1);
                        }
                    }
                    record.setListeningSeat(serviceBusDetailDTO.getBusType());
                    break;
                }
            }
            record.setUpdateTime(new Date());
            listeningInfoMapper.updateByPrimaryKeySelective(record);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void pushMP(String keywordsStr1, String keywordsStr2, String openId, String formId) throws Exception {
        String host = "https://api.weixin.qq.com";
        String path = "/cgi-bin/message/wxopen/template/send";
        Map<String, String> headers = new HashMap<>();
        Map<String, String> querys = new HashMap<>();
        querys.put("access_token", getAccessToken());

        JSONObject dataJson = new JSONObject();
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", keywordsStr1);
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", keywordsStr2);


        dataJson.put("keyword1", keyword1);
        dataJson.put("keyword2", keyword2);

        JSONObject body = new JSONObject();
        body.put("touser", openId);
        body.put("template_id", "4YvOrBW6LtuhpX5SCCeeKbyOpKFQGrZ-BGm_-pXTJlg");
        body.put("form_id", formId);
        body.put("data", dataJson);


        HttpResponse response = HttpUtils.doPostWithJsonBody(host, path, "POST", headers, querys, body.toString());
        String result = EntityUtils.toString(response.getEntity());
        LOG.info(formId + " " + result);
    }

    public String getAccessToken() {
        String reslut = valueOs.get("config-mpAccessToken");
        if (StringUtils.isEmpty(reslut)) {
            String host = "https://api.weixin.qq.com";
            String path = "/cgi-bin/token";
            Map<String, String> headers = new HashMap<>();
            Map<String, String> querys = new HashMap<>();
            Map<String, String> bodys = new HashMap<>();
            querys.put("grant_type", "client_credential");
            querys.put("appid", "wxa3f5269ed575a816");
            querys.put("secret", "6cd0d8bec09f4d450acd07abaabb356d");
            HttpResponse response = null;
            try {
                response = HttpUtils.doPost(host, path, "GET", headers, querys, bodys);
            } catch (Exception e) {
                e.printStackTrace();
            }
            String result = null;
            JSONObject jsonObject;
            try {
                result = EntityUtils.toString(response.getEntity());
                jsonObject = JSONObject.parseObject(result);
                result = jsonObject.getString("access_token");
                valueOs.set("config-mpAccessToken", result, 20, TimeUnit.MINUTES);
            } catch (IOException e) {
                e.printStackTrace();
            }
            LOG.info(result);
        }
        return reslut;
    }


    /**
     * 过期车次
     *
     * @param listeningInfoPO
     * @param date
     * @param time
     */
    private void overdue(ListeningInfo listeningInfoPO, String date, String time) {
        try {
            //过期车次
            if (MyDateUtils.stringToDate(date + " " + time).getTime() < System.currentTimeMillis()) {
                ListeningInfo record = new ListeningInfo();
                record.setListeningId(listeningInfoPO.getListeningId());
                record.setOverdue(1);
                record.setUpdateTime(new Date());
                listeningInfoMapper.updateByPrimaryKeySelective(record);
            }

        } catch (Exception e) {
            ListeningInfo record = new ListeningInfo();
            record.setListeningId(listeningInfoPO.getListeningId());
            record.setOverdue(1);
            record.setUpdateTime(new Date());
            listeningInfoMapper.updateByPrimaryKeySelective(record);
        }
    }
}
